package View;

import Model.ClientMessageReceiver;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;

/**
 *
 * @author kiko
 */
public class MainMenu extends javax.swing.JFrame {

    ClientMessageReceiver clientMessageReceiver;
    Socket connection;
    
    /**
     * Creates new form MainMenu
     */
    MainMenu(Socket connection) {
        initComponents();
        this.connection = connection;
        clientMessageReceiver = new ClientMessageReceiver(connection);
        clientMessageReceiver.start();
        updateTable();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPopupMenu1 = new javax.swing.JPopupMenu();
        jButtonPermission = new javax.swing.JButton();
        jButtonDownload = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        jTableFiles = new javax.swing.JTable();
        jButtonUpdateTable = new javax.swing.JButton();
        jButtonUploadFile = new javax.swing.JButton();
        jButtonDeleteFile = new javax.swing.JButton();
        jButtonExit = new javax.swing.JButton();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        jMenu2 = new javax.swing.JMenu();
        jMenu4 = new javax.swing.JMenu();
        jMenu3 = new javax.swing.JMenu();
        jMenuItem1 = new javax.swing.JMenuItem();
        jMenuItem2 = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jButtonPermission.setText("Modify");
        jButtonPermission.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonPermissionActionPerformed(evt);
            }
        });

        jButtonDownload.setText("Download file");
        jButtonDownload.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonDownloadActionPerformed(evt);
            }
        });

        jTableFiles.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        jScrollPane1.setViewportView(jTableFiles);

        jButtonUpdateTable.setText("Update table");
        jButtonUpdateTable.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonUpdateTableActionPerformed(evt);
            }
        });

        jButtonUploadFile.setText("Upload file");
        jButtonUploadFile.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonUploadFileActionPerformed(evt);
            }
        });

        jButtonDeleteFile.setText("Delete file");
        jButtonDeleteFile.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonDeleteFileActionPerformed(evt);
            }
        });

        jButtonExit.setText("Exit");
        jButtonExit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonExitActionPerformed(evt);
            }
        });

        jMenu1.setText("File");
        jMenuBar1.add(jMenu1);

        jMenu2.setText("Edit");
        jMenuBar1.add(jMenu2);

        jMenu4.setText("View");
        jMenuBar1.add(jMenu4);

        jMenu3.setText("Tools");

        jMenuItem1.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_W, java.awt.event.InputEvent.SHIFT_MASK | java.awt.event.InputEvent.CTRL_MASK));
        jMenuItem1.setText("Connect to server");
        jMenu3.add(jMenuItem1);

        jMenuItem2.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Q, java.awt.event.InputEvent.SHIFT_MASK | java.awt.event.InputEvent.CTRL_MASK));
        jMenuItem2.setText("Disconnect to server");
        jMenu3.add(jMenuItem2);

        jMenuBar1.add(jMenu3);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                            .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                                .addComponent(jButtonUploadFile, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(18, 18, 18)
                                .addComponent(jButtonDeleteFile, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                            .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                                .addComponent(jButtonDownload, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(18, 18, 18)
                                .addComponent(jButtonPermission, javax.swing.GroupLayout.PREFERRED_SIZE, 180, javax.swing.GroupLayout.PREFERRED_SIZE)))
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jButtonUpdateTable, javax.swing.GroupLayout.DEFAULT_SIZE, 180, Short.MAX_VALUE)
                            .addComponent(jButtonExit, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 275, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButtonDownload)
                    .addComponent(jButtonPermission)
                    .addComponent(jButtonUpdateTable))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButtonUploadFile)
                    .addComponent(jButtonDeleteFile)
                    .addComponent(jButtonExit))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButtonPermissionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonPermissionActionPerformed
        String fileName;
        try {
            BufferedReader bw = new BufferedReader(new FileReader("permissions" + File.separator + jTableFiles.getValueAt(jTableFiles.getSelectedRow(),0).toString()));
            String keyword = bw.readLine();
            bw.close();
            fileName = jTableFiles.getValueAt(jTableFiles.getSelectedRow(),0).toString();
            DataOutputStream out = new DataOutputStream(connection.getOutputStream());
            out.writeBytes("PERM:" + fileName + ":" + keyword + "\n");
        } catch(ArrayIndexOutOfBoundsException e) {
            JOptionPane.showMessageDialog(null, "Nenhum arquivo selecionado.");
        } catch (IOException e) {
            JOptionPane.showMessageDialog(null, "Arquivo já em uso. Tente novamente mais tarde.");
        }
    }//GEN-LAST:event_jButtonPermissionActionPerformed

    private void jButtonDownloadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonDownloadActionPerformed
        String fileName = JOptionPane.showInputDialog(null, "Enter the file name", null, 1);
        try {
            DataOutputStream out = new DataOutputStream(connection.getOutputStream());
            out.writeBytes("GETF:" + fileName + "\n");
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(null, "Erro! Impossível fazer download.");
        }
        try {
            BufferedWriter bw = new BufferedWriter(new FileWriter("permissions" + File.separator + fileName));
            bw.write("read only\n");
            bw.close();
        } catch(IOException e) {
            deleteFile("permissions" + File.separator + fileName);
            JOptionPane.showMessageDialog(null, "Erro! Erro de download.");
        }
    }//GEN-LAST:event_jButtonDownloadActionPerformed

    private void jButtonUpdateTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonUpdateTableActionPerformed
        updateTable();
    }//GEN-LAST:event_jButtonUpdateTableActionPerformed

    private void jButtonDeleteFileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonDeleteFileActionPerformed
        try {
            String path = "permissions" + File.separator + jTableFiles.getValueAt(jTableFiles.getSelectedRow(), 0).toString();
            deleteFile(path);
            path = "files" + File.separator + jTableFiles.getValueAt(jTableFiles.getSelectedRow(), 0).toString();
            deleteFile(path);
            updateTable();
            JOptionPane.showMessageDialog(null, "File deleted!");
        } catch(ArrayIndexOutOfBoundsException e) {
            JOptionPane.showMessageDialog(null, "No file selected!");
        }
    }//GEN-LAST:event_jButtonDeleteFileActionPerformed

    private void jButtonExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonExitActionPerformed
        System.exit(0);
    }//GEN-LAST:event_jButtonExitActionPerformed

    private void jButtonUploadFileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonUploadFileActionPerformed
        JFileChooser chooser = new JFileChooser();
        String path = null;
        int retorno = chooser.showSaveDialog(null);
        if (retorno == JFileChooser.APPROVE_OPTION) {
            try {
                path = chooser.getSelectedFile().getAbsolutePath();
                DataOutputStream out = new DataOutputStream(connection.getOutputStream());
                out.writeBytes("UPDT\n");
                ServerSocket welcome = new ServerSocket(50400);
                Socket aux = welcome.accept();
                sendFile(aux, path);
                aux.close();
                welcome.close();
                
                BufferedReader br = new BufferedReader(new FileReader(path));
                BufferedWriter bw = new BufferedWriter(new FileWriter("files" + File.separator + chooser.getSelectedFile().getName()));
                while (br.ready()) {
                    String st = br.readLine();
                    bw.write(st + "\n");
                }
                bw.close();
                bw = new BufferedWriter(new FileWriter("permissions" + File.separator + chooser.getSelectedFile().getName()));
                bw.write("read only");
                br.close();
                bw.close();
            } catch (IOException ex) {
                JOptionPane.showMessageDialog(null, "Erro. Não foi possível enviar o arquivo.");
                this.dispose();
            }
        }
    }//GEN-LAST:event_jButtonUploadFileActionPerformed

    public void sendFile(Socket aux, String path) {
        try {
            File file = new File(path);
            ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(aux.getOutputStream()));
            out.writeUTF(file.getName());
            out.writeLong(file.length());
            BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));

            byte[] buf = new byte[4096];
            while (true) {
                int len = in.read(buf);
                if (len == -1) {
                    break;
                }
                out.write(buf, 0, len);
                out.flush();
            }
            in.close();
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(null, "Erro! Não foi possível enviar o arquivo.");
        }
    }
    
    private void deleteFile(String path) {
        File file = new File(path);
        file.delete();
    }
    
    private void updateTable() {
        BufferedReader br;
        File diretorio = new File("files");
        File fList[] = diretorio.listFiles();
        String[][] files = new String[fList.length][2];
        int i = 0;
        try {
            for (File dir : fList) {
                files[i][0] = dir.getName();
                br = new BufferedReader(new FileReader("permissions" + File.separator + files[i][0]));
                if (br.readLine().equals("read only")) {
                    files[i][1] = "read only";
                } else {
                    files[i][1] = "read and write";
                }
                i++;
                br.close();
            }
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(null, "Ocorreu um erro ao tentar atualizar a tabela de arquivos");
        }
        setTable(files);
    }
    
    private void setTable(String[][] body) {
        String[] title = {
            "File", "Permission"
        };
        jTableFiles.setModel(new javax.swing.table.DefaultTableModel(body, title));
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonDeleteFile;
    private javax.swing.JButton jButtonDownload;
    private javax.swing.JButton jButtonExit;
    private javax.swing.JButton jButtonPermission;
    private javax.swing.JButton jButtonUpdateTable;
    private javax.swing.JButton jButtonUploadFile;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenu jMenu2;
    private javax.swing.JMenu jMenu3;
    private javax.swing.JMenu jMenu4;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JMenuItem jMenuItem2;
    private javax.swing.JPopupMenu jPopupMenu1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable jTableFiles;
    // End of variables declaration//GEN-END:variables
}
